#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <memory>

const std::string sep = "\r\n";

class HttpRequest
{
private:
    std::string GetOneline(std::string &reqstr)
    {
        if (reqstr.empty())
            return reqstr;
        auto pos = reqstr.find(sep);
        if (pos == std::string::npos)
            return std::string();

        std::string line = reqstr.substr(0, pos);
        reqstr.erase(0, pos + sep.size());
        return line.empty() ? sep : line;
    }

public:
    HttpRequest() : _blank_line(sep)
    {
    }

    void Serialize() {}
    void Derialize(std::string &reqstr)
    {
        _req_line = GetOneline(reqstr);
        while (true)
        {
            std::string line = GetOneline(reqstr);
            if (line.empty())
                break;
            else if (line == sep)
            {
                _req_text = reqstr;
                break;
            }
            else
            {
                _req_header.emplace_back(line);
            }
        }
    }
    void Print()
    {
        std::cout << "===" << _req_line << std::endl;
        for (auto &header : _req_header)
        {
            std::cout << "***" << header << std::endl;
        }
        std::cout << _blank_line;
        std::cout << _req_text << std::endl;
    }
    ~HttpRequest() {}

private:
    std::string _req_line;
    std::vector<std::string> _req_header;
    std::string _blank_line;
    std::string _req_text;
};

class HttpResponse
{
public:
private:
    std::string _status_line;
    std::vector<std::string> _resp_header;
    std::string _blank_line;
    std::string _resp_text;
};

class Factory
{
public:
    static std::shared_ptr<HttpRequest> Buildrequest()
    {
        return std::make_shared<HttpRequest>();
    }
};

class HttpServer
{
public:
    HttpServer() {}
    std::string HandlerHttpReqeust(std::string req)
    {
#ifdef TEST
        std::cout << "------------------------------------" << std::endl;
        std::cout << req;

        std::string response = "HTTP/1.0 200 OK\r\n";
        response += "\r\n";
        response += "<html><body><h1>hello world, hello bite!</h1></body></html>";
        return response;
#else
        auto request = Factory::Buildrequest();
        request->Derialize(req);
        request->Print();

        std::string response = "HTTP/1.0 200 OK\r\n";
        response += "\r\n";
        response += "<html><body><h1>hello world, hello bite!</h1></body></html>";
        return response;
#endif
    }
    ~HttpServer() {}

private:
};